package com.changpei.common.http;

import lombok.Data;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.util.ObjectUtils;

import javax.net.ssl.SSLContext;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 *
 *
 * @author Way on 2021/8/6
 */
@Data
public class HttpClient {

    /**
     * 访问地址
     */
    private String url;

    /**
     * 参数
     */
    private Map<String, String> param;

    /**
     * 响应状态码
     */
    private int statusCode;

    /**
     * 响应内容
     */
    private String content;

    /**
     * xml参数
     */
    private String xmlParam;

    /**
     * 是否安全访问
     */
    private boolean isHttps;

    public HttpClient(String url, Map<String, String> param) {
        this.url = url;
        this.param = param;
    }

    public HttpClient(String url) {
        this.url = url;
    }

    /**
     * 添加参数
     * @param key
     * @param value
     */
    public void addParameter(String key, String value) {
        if (ObjectUtils.isEmpty(param)) {
            param = new HashMap<>(16);
        }
        param.put(key, value);
    }

    /**
     * post请求
     *
     * @throws Exception
     */
    public void post() throws Exception {
        HttpPost http = new HttpPost(url);
        setEntity(http);
        execute(http);
    }

    /**
     * put请求
     *
     * @throws Exception
     */
    public void put() throws Exception {
        HttpPut http = new HttpPut(url);
        setEntity(http);
        execute(http);
    }

    /**
     * get请求
     *
     * @throws Exception
     */
    public void get() throws Exception {
        if (!ObjectUtils.isEmpty(param)) {
            StringBuilder url = new StringBuilder(this.url);
            boolean isFirst = true;
            for (String key : param.keySet()) {
                if (isFirst) {
                    url.append("?");
                    isFirst = false;
                } else {
                    url.append("&");
                }
                url.append(key).append("=").append(param.get(key));
            }
            this.url = url.toString();
        }
        HttpGet http = new HttpGet(url);
        execute(http);
    }

    /**
     * 设置post,put请求参数
     * @param http
     */
    private void setEntity(HttpEntityEnclosingRequestBase http) {
        if (!ObjectUtils.isEmpty(param)) {
            List<NameValuePair> nameValuePairs = new LinkedList<>();
            for (String key : param.keySet()) {
                // 参数
                nameValuePairs.add(new BasicNameValuePair(key, param.get(key)));
            }
            // 设置参数
            http.setEntity(new UrlEncodedFormEntity(nameValuePairs, Consts.UTF_8));
        }
        if (!ObjectUtils.isEmpty(xmlParam)) {
            http.setEntity(new StringEntity(xmlParam, Consts.UTF_8));
        }
    }

    private void execute(HttpUriRequest http) throws Exception {
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;

        try {
            // 初始化httpClient
            if (isHttps) {
                // 信任所有
                SSLContext sslContext = new SSLContextBuilder()
                        .loadTrustMaterial(null, (TrustStrategy) (x509Certificates, s) -> true).build();
                SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext);
                httpClient = HttpClients.custom()
                        .setSSLSocketFactory(sslConnectionSocketFactory)
                        .build();
            } else {
                httpClient = HttpClients.createDefault();
            }

            // 执行请求
            response = httpClient.execute(http);

            if (!ObjectUtils.isEmpty(response)) {
                if (!ObjectUtils.isEmpty(response.getStatusLine())) {
                    // 设置响应状态码
                    this.setStatusCode(response.getStatusLine().getStatusCode());
                }

                HttpEntity entity = response.getEntity();
                // 设置响应内容
                this.setContent(EntityUtils.toString(entity, Consts.UTF_8));
            }
        } finally {
            if (!ObjectUtils.isEmpty(httpClient)) {
                httpClient.close();
            }

            if (!ObjectUtils.isEmpty(response)) {
                response.close();
            }
        }
    }
}
